### Version History

###Restructure v.02 changes:
### Testing key events within the main game loop
### Adding transition from game loop back to shell loop

### Restructure v.01 changes
### Restructure Code as per program structure file

### v.09 changes
### separation of textobjects into a separate class
### creation of menu function to handle display of menu items

### v.08 changes
### add game over screen which displays final score, and asks the player whether to start again, or quit

### v.07 changes:
### add score and lives variables to the test function
### test the transition from the game to the game over screen

### v.06 changes:
### define a function to show the test display, and start the function when start is selected and 'enter' is pressed. 
### This test function is a placeholder for the main game function running inside the main shell loop

### v.05 changes:
### create test display to test starting the game

### v.04 changes:
### Test key events to switch selection and test quitting the game

### v.03 changes:
### introduce menumode and selected variables
### define key events to switch selection if in menumode

###  v.02 changes:
### changes text displayed on screen after a short pause
### creates new main class to initialise the game


###1. Import modules:

import pygame
from pygame.locals import *
import sys

### 2: Declare public variables
### these variables need to be accessible to various functions in various classes


screenWidth = 800
screenHeight = 600
screenSize = screenWidth, screenHeight

"""menumode keeps track of the gamestate - allowed values are: -2 - opening screen is displayed, no menu available, 0 - control map is displayed, 1 - start menu displayed, -1 - main game loop running, no menu displayed, 2 - restart menu displayed"""
menumode = -2 

"""the selected variable keeps track of which menuitem the player has selected. It can have the following values: 0 - no selectable item displayed,  1 - first/upper menuitem selected; -1 - lower/second menuitem selected"""
selected = 0

score = 0
finalScore = 0


### 3. Define classes

class BugsMain:

	def __init__(self): 

    		##initialise pygame
    		pygame.init()

	
   	 	## create the display
    		self.screen = pygame.display.set_mode(screenSize)
		pygame.display.set_caption("Bugs!")

    		self.background = pygame.Surface(self.screen.get_size()) #ensures background is the same size as the game window
 		self.background = self.background.convert()
   		self.background.fill((0, 0, 0))

    		## make the background visible and refresh
		self.screen.blit(self.background, (0, 0))
	      	pygame.display.flip()

	def MenuKeyMap(self):
		"""This function displays the keymap to the player and waits for any key to be pressed before transition to the start/quit menu"""

		global menumode
		global selected

		self.screen.blit(self.background, (0,0))
		pygame.display.flip()


		##initialise text objects 

		textControls = BugsText(None, 64)
		textControls.write("Controls", (0, 0, 255))
		textControls.adjustPos(0, -230)
		
		textKeyNav = BugsText(None, 36)
		textKeyNav.write("Up and Down arrows - navigate menu", (164, 164, 164))
		textKeyNav.adjustPos(0, -165)

		textEnter = BugsText(None, 36)
		textEnter.write("Enter - confirm selection", (164, 164, 164))
		textEnter.adjustPos(0, -90)

		textQuit = BugsText(None, 36)
		textQuit.write("Esc - quit", (164, 164, 164))
		textQuit.adjustPos(0, -15)			
		
		textMove = BugsText(None, 36)
		textMove.write("Left and Right arrows - move player", (164, 164, 164))
		textMove.adjustPos(0, 60)

		textShoot = BugsText(None, 36)
		textShoot.write("Spacebar - fire missile", (164, 164, 164))
		textShoot.adjustPos(0, 135)

		textContinue = BugsText(None, 24)
		textContinue.write("Press any key to continue", (128, 128, 128))
		textContinue.adjustPos(0, 200)


		## display text objects

		self.screen.blit(textControls.message, textControls.pos)
		self.screen.blit(textKeyNav.message, textKeyNav.pos)
		self.screen.blit(textEnter.message, textEnter.pos)
		self.screen.blit(textQuit.message, textQuit.pos)
		self.screen.blit(textMove.message, textMove.pos)
		self.screen.blit(textShoot.message, textShoot.pos)
		self.screen.blit(textContinue.message, textContinue.pos)
		pygame.display.flip()

		"""This function waits for input from the player once all text objects are displayed"""

		



		



	def MenuStart(self):
		"""This function displays the Start/Quit menu with 'Start selected and modifies the 'selected' variable accordingly"""

		global selected

		self.screen.blit(self.background, (0,0))
		pygame.display.flip()
		
		textStartS = BugsText(None, 48)
		textStartS.write("START", (255, 64, 64))
		textStartS.adjustPos(0, -50)

		textQuit = BugsText(None, 48)
		textQuit.write("QUIT",  (166, 166, 166))
		textQuit.adjustPos(0, 50)
			
		self.screen.blit(textStartS.message, textStartS.pos)
		self.screen.blit(textQuit.message, textQuit.pos)
		pygame.display.flip()

		
		selected = 1
		return

		"""This function waits for input from the player once text objects are displayed"""

		


	def MenuStartQSelect(self):
		"""This function is called when the selection in the start/quit menu is reversed. 'Quit' is now displayed as selected, and the 'selected' variable modified accordingly"""

		global selected

		self.screen.blit(self.background, (0,0))
		pygame.display.flip()
		
		textStart = BugsText(None, 48)
		textStart.write("START", (166, 166, 166))
		textStart.adjustPos(0, -50)

		textQuitS = BugsText(None, 48)
		textQuitS.write("QUIT",  (255, 64, 64))
		textQuitS.adjustPos(0, 50)
			
		self.screen.blit(textStart.message, textStart.pos)
		self.screen.blit(textQuitS.message, textQuitS.pos)
		pygame.display.flip()

		selected = -1
		return

		"""This function waits for input from the player once text objects are displayed"""


	def MenuGameOver(self):
		"""This function deals with the transition from the MainGame loop back to the shell loop. It displays the players final scor and asks if they want to play again."""
	
		global menumode
		global score
		global selected

		finalScore = getScore(self)

		self.screen.fill((0, 0, 0))
		pygame.display.flip()

		textGameOver = BugsText(None, 128)
		textGameOver.write("GAME OVER!", (255, 0, 0))
		textGameOver.adjustPos(0, 0)
		self.screen.blit(textGameOver.message, textGameOver.pos)
		pygame.display.flip()

		pygame.time.delay(2500)

		self.screen.blit(self.background, (0, 0))
		pygame.display.flip()


		## get the last value of score and display it as final score
		textFinalScore = BugsText(None, 56)
		textFinalScore.write("Your final score is: " + finalScore, (0,255,0))
		textFinalScore.adjustPos(0, -75)
		
		textPlayAgain = BugsText(None, 48)
		textPlayAgain.write("Select 'Start' to play again or 'Quit' to exit", (164, 164, 164))
		textPlayAgain.adjustPos (0, 50)
		
		self.screen.blit(textFinalScore.message, textFinalScore.pos)
		self.screen.blit(textPlayAgain.message, textPlayAgain.pos)
		pygame.display.flip()

		pygame.time.delay(5000)
		menumode = 1
		selected = 1

		MainWindow.MenuStart()	
		

			

	def MainGameLoop(self):
		"""This is where the game will run inside the shell loop"""

		global menumode
		global score

		score = 0
		lives = 3

		scoreDisplay = getScore(self)

		##this is a placeholder screen

		self.screen.blit(self.background, (0,0))
		pygame.display.flip()
		
		textTest = BugsText(None, 48)
		textTest.write("you see many alien bugs", (0, 255, 0))
		textTest.adjustPos(0, 0)

		textScore = BugsText(None, 24)
		textScore.write("Score: " + scoreDisplay, (0, 0, 255))
		textScore.adjustPos(350, -250)

		self.screen.blit(textTest.message, textTest.pos)
		self.screen.blit(textScore.message, textScore.pos)
		pygame.display.flip()

		while lives > 0:
			pygame.time.delay(2500)
			lives -= 1
			print lives

		score = 65784


		### end of placeholder

		"""Once the variable 'lives' has reached 0 this function changes the value of menumode and uses the MenuGameOver function to display the gameover screen"""
		
		menumode = 2
		MainWindow.MenuGameOver()

		
		

		


	def ShellLoop(self):

		"""This is where all the events in the game will run"""

		global menumode 
		global selected 

		### initialise opening display
		textWelcome = BugsText(None, 48)
		textWelcome.write("Splat the bugs and win fabulous prizes!", (255, 0, 0))
		textWelcome.adjustPos(0, 0)
		
		self.screen.blit(textWelcome.message, textWelcome.pos)
    		pygame.display.flip()

		pygame.time.delay(5000)

		menumode = 0
		MainWindow.MenuKeyMap()

		
		


		while 1:
			for event in pygame.event.get():
				if event.type == QUIT:
					return

				elif event.type == KEYDOWN:

					if menumode == 0: ## pressing any key during this stage triggers MenuStart
						menumode = 1
						MainWindow.MenuStart()

					elif event.key == K_ESCAPE: #player chooses to exit the game
						return

					elif menumode == 1: #starting menu is displayed
						if event.key == K_UP:
							if selected == -1: # 'quit' is currently selected,
								MainWindow.MenuStart()
						
            
						if event.key == K_DOWN:
							if selected == 1: # 'start' is currently selected
								MainWindow.MenuStartQSelect()


						if event.key == K_RETURN:
              						if selected == -1:   ## if 'quit' is selected when return key pressed, game exits
								sys.exit("bye-bye!")

							elif selected == 1: ## if 'start' is selected when return key pressed, main game starts
								selected = 0 #reset selected variable
								menumode = -1 #set menumode to indicate that the main game is now running                
								MainWindow.MainGameLoop()


					


		
		


class BugsText(pygame.font.Font):
  	"""This is the class that will handle text objects and their attributes"""  

  	def __init__(self, font_name, size):
    		pygame.font.Font.__init__(self, None, size)

	def write(self, message, color):
    		self.message = self.render(message, 1, color)
		self.pos = self.message.get_rect()
   

	def adjustPos(self, adjustX, adjustY):
		self.pos.centerx = screenWidth/2 + adjustX
		self.pos.centery = screenHeight/2 +adjustY
 
  	



### Sprite class goes here

### Player class goes here

### Missile class goes here

### Hostiles class goes here

###  Shield class goes here



### 4. Define functions

def getScore(self):
	global score
	return(str(score))






### Start Main class


if __name__ == '__main__':
  MainWindow = BugsMain()
  MainWindow.ShellLoop()





   


